using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.Threading;

using SIMA.Entities;
using SIMA.Core.Data.Collection;
using SIMA.Core.Data.Access;
using SIMA.Core.Enums;
using SIMA.Core.EventArgs;
using SIMA.Core.Security;

namespace SIMA.Services
{

	public class T_C_UsuarioService : IT_C_UsuarioService
	{
		#region Fields

		private SmartContainer<T_C_Usuario> dataAccessSmart;
		private FailedEventArgs onFailed;
		private InsertedEventArgs onInserted;
		private UpdatedEventArgs onUpdated;
		private DeletedEventArgs onDeleted;
        private FilterType filter;
        private T_C_Usuario tmpUsuario1, tmpUsuario2;
		private static Semaphore ResourceLock;

		#endregion

		#region Constructor

		public T_C_UsuarioService()
		{
			DataAccess.SetConnection(SIMA.Core.Enums.AccessType.FromString, "Data Source=.;Initial Catalog=SIMA;Integrated Security=True");
			ResourceLock = new Semaphore(0, 2);
			dataAccessSmart = new SmartContainer<T_C_Usuario>(false,true);
			dataAccessSmart.Inserted += new EventHandler<InsertedEventArgs>(dataAccessSmart_Inserted);
			dataAccessSmart.Failed += new EventHandler<FailedEventArgs>(dataAccessSmart_Failed);
			dataAccessSmart.Updated += new EventHandler<UpdatedEventArgs>(dataAccessSmart_Updated);
			dataAccessSmart.Deleted += new EventHandler<DeletedEventArgs>(dataAccessSmart_Deleted);
		}

		#endregion

		#region Implementacion de eventos del SmartContainer

        private void dataAccessSmart_Inserted(object sender, InsertedEventArgs e)
        {
            onInserted = e;
        }

        private void dataAccessSmart_Updated(object sender, UpdatedEventArgs e)
        {
            onUpdated = e;
        }

        private void dataAccessSmart_Deleted(object sender, DeletedEventArgs e)
        {
            onDeleted = e;
        }

        private void dataAccessSmart_Failed(object sender, FailedEventArgs e)
        {
            onFailed = e;
        }

		#endregion

		#region Implementando la interfaz de servicio

        #region Get All

        public List<T_C_Usuario> GetAllT_C_Usuario(Profile securityProfile)
        {
            SecurityProgram.PcProfile = securityProfile;
            dataAccessSmart.SelectAll();
            return dataAccessSmart.ToList();
        }

        public IAsyncResult BeginGetAllT_C_Usuario(Profile securityProfile, AsyncCallback callback, object state)
        {
            T_C_UsuarioAsyncResult asyncResult = new T_C_UsuarioAsyncResult(securityProfile, callback, state);
            ThreadPool.QueueUserWorkItem(new WaitCallback((GetAllT_C_UsuarioCallback)), asyncResult);
            return asyncResult;
        }

        private void GetAllT_C_UsuarioCallback(object asyncResult)
        {
            T_C_UsuarioAsyncResult getT_C_UsuarioAsyncResult = (T_C_UsuarioAsyncResult)asyncResult;
            try
            {
                getT_C_UsuarioAsyncResult.CollectionResult = GetAllT_C_Usuario(SecurityProgram.PcProfile);
                getT_C_UsuarioAsyncResult.ExceptionTrace = null;
                getT_C_UsuarioAsyncResult.MessageResult = string.Empty;
            }
            catch (Exception ex)
            {
                getT_C_UsuarioAsyncResult.CollectionResult = null;
                getT_C_UsuarioAsyncResult.ExceptionTrace = ex;
                getT_C_UsuarioAsyncResult.MessageResult = string.Empty;
            }
            finally
            {
                getT_C_UsuarioAsyncResult.OnCompleted();
            }
        }

        public List<T_C_Usuario> EndGetAllT_C_Usuario(IAsyncResult asyncResult)
        {
            List<T_C_Usuario> lista = null;
            using (T_C_UsuarioAsyncResult getT_C_UsuarioResult = asyncResult as T_C_UsuarioAsyncResult)
            {
                getT_C_UsuarioResult.AsyncWaitHandle.WaitOne();
                lista = getT_C_UsuarioResult.CollectionResult;
            }
            return lista;
        }

        #endregion

        #region Get Filtered

        public List<T_C_Usuario> GetFilteredT_C_Usuario(Profile securityProfile, FilterType filter)
        {
            List<T_C_Usuario> lista = null;
            this.filter = filter;
            SecurityProgram.PcProfile = securityProfile;
            switch (filter)
            {
                case FilterType.Active:
                    lista = dataAccessSmart["SelectActiveUsuario", CommandType.StoredProcedure];
                    break;
                case FilterType.Inactive:
                    lista = dataAccessSmart["SelectInactiveUsuario", CommandType.StoredProcedure];
                    break;
            }
            return lista;
        }

        public IAsyncResult BeginGetFilteredT_C_Usuario(Profile securityProfile, FilterType filter, AsyncCallback callback, object state)
        {
            T_C_UsuarioAsyncResult asyncResult = new T_C_UsuarioAsyncResult(securityProfile, callback, state);
            ThreadPool.QueueUserWorkItem(new WaitCallback((GetFilteredT_C_UsuarioCallback)), asyncResult);
            return asyncResult;
        }

        private void GetFilteredT_C_UsuarioCallback(object asyncResult)
        {
            T_C_UsuarioAsyncResult getT_C_UsuarioAsyncResult = (T_C_UsuarioAsyncResult)asyncResult;
            try
            {
                getT_C_UsuarioAsyncResult.CollectionResult = GetFilteredT_C_Usuario(SecurityProgram.PcProfile, this.filter);
                getT_C_UsuarioAsyncResult.ExceptionTrace = null;
                getT_C_UsuarioAsyncResult.MessageResult = string.Empty;
            }
            catch (Exception ex)
            {
                getT_C_UsuarioAsyncResult.CollectionResult = null;
                getT_C_UsuarioAsyncResult.ExceptionTrace = ex;
                getT_C_UsuarioAsyncResult.MessageResult = string.Empty;
            }
            finally
            {
                getT_C_UsuarioAsyncResult.OnCompleted();
            }
        }

        public List<T_C_Usuario> EndGetFilteredT_C_Usuario(IAsyncResult asyncResult)
        {
            List<T_C_Usuario> lista = null;
            using (T_C_UsuarioAsyncResult getT_C_UsuarioResult = asyncResult as T_C_UsuarioAsyncResult)
            {
                getT_C_UsuarioResult.AsyncWaitHandle.WaitOne();
                lista = getT_C_UsuarioResult.CollectionResult;
            }
            return lista;
        }

        #endregion

        #region New

        public string RegisterT_C_Usuario(Profile securityProfile, T_C_Usuario newItem)
        {
            SecurityProgram.PcProfile = securityProfile;
            tmpUsuario1 = newItem;
            dataAccessSmart.Add(newItem);
            ResourceLock.WaitOne(1000);
            ResourceLock.Release();
            return "Nuevo registro de usuario creado.";
        }

        public IAsyncResult BeginRegisterT_C_Usuario(Profile securityProfile, T_C_Usuario newItem, AsyncCallback callback, object state)
        {
            T_C_UsuarioAsyncResult asyncResult = new T_C_UsuarioAsyncResult(securityProfile, callback, state);
            ThreadPool.QueueUserWorkItem(new WaitCallback((RegisterT_C_UsuarioCallback)), asyncResult);
            return asyncResult;
        }

        private void RegisterT_C_UsuarioCallback(object asyncResult)
        {
            T_C_UsuarioAsyncResult t_c_UsuarioAsyncResult = (T_C_UsuarioAsyncResult)asyncResult;
            try
            {
                t_c_UsuarioAsyncResult.CollectionResult = null;
                t_c_UsuarioAsyncResult.ExceptionTrace = null;
                t_c_UsuarioAsyncResult.MessageResult = RegisterT_C_Usuario(SecurityProgram.PcProfile, tmpUsuario1);

            }
            catch (Exception ex)
            {
                t_c_UsuarioAsyncResult.CollectionResult = null;
                t_c_UsuarioAsyncResult.ExceptionTrace = ex;
                t_c_UsuarioAsyncResult.MessageResult = string.Empty;
            }
            finally
            {
                t_c_UsuarioAsyncResult.OnCompleted();
                tmpUsuario1 = null;
            }
        }

        public string EndRegisterT_C_Usuario(IAsyncResult asyncResult)
        {
            string msg = string.Empty;
            using (T_C_UsuarioAsyncResult t_c_UsuarioAsyncResult = asyncResult as T_C_UsuarioAsyncResult)
            {
                asyncResult.AsyncWaitHandle.WaitOne();
                msg = t_c_UsuarioAsyncResult.MessageResult;
            }
            return msg;
        }
        
        #endregion        

        #region Update

        public string UpdateT_C_Usuario(Profile securityProfile, T_C_Usuario itemToUpdate, T_C_Usuario itemUpdated)
        {
            SecurityProgram.PcProfile = securityProfile;
            tmpUsuario1 = itemToUpdate;
            tmpUsuario2 = itemUpdated;
            dataAccessSmart.Update(tmpUsuario1, tmpUsuario2);
            ResourceLock.WaitOne(1000);
            return "Cambio de usuario realizado.";
        }

        public IAsyncResult BeginUpdateT_C_Usuario(Profile securityProfile, T_C_Usuario itemToUpdate, T_C_Usuario itemUpdated, AsyncCallback callback, object state)
        {
            T_C_UsuarioAsyncResult asyncResult = new T_C_UsuarioAsyncResult(securityProfile, callback, state);
            ThreadPool.QueueUserWorkItem(new WaitCallback((UpdateT_C_UsuarioCallback)), asyncResult);
            return asyncResult;
        }

        private void UpdateT_C_UsuarioCallback(object asyncResult)
        {
            T_C_UsuarioAsyncResult t_c_UsuarioAsyncResult = (T_C_UsuarioAsyncResult)asyncResult;
            try
            {
                t_c_UsuarioAsyncResult.CollectionResult = null;
                t_c_UsuarioAsyncResult.ExceptionTrace = null;
                t_c_UsuarioAsyncResult.MessageResult = UpdateT_C_Usuario(SecurityProgram.PcProfile, tmpUsuario1, tmpUsuario2);

            }
            catch (Exception ex)
            {
                t_c_UsuarioAsyncResult.CollectionResult = null;
                t_c_UsuarioAsyncResult.ExceptionTrace = ex;
                t_c_UsuarioAsyncResult.MessageResult = string.Empty;
            }
            finally
            {
                t_c_UsuarioAsyncResult.OnCompleted();
                tmpUsuario1 = null;
                tmpUsuario2 = null;
            }
        }

        public string EndUpdateT_C_Usuario(IAsyncResult asyncResult)
        {
            string msg = string.Empty;
            using (T_C_UsuarioAsyncResult t_c_UsuarioAsyncResult = asyncResult as T_C_UsuarioAsyncResult)
            {
                asyncResult.AsyncWaitHandle.WaitOne();
                msg = t_c_UsuarioAsyncResult.MessageResult;
            }
            return msg;
        }

        #endregion               

        #region Delete

        public string DeleteT_C_Usuario(Profile securityProfile, T_C_Usuario dropItem)
        {
            SecurityProgram.PcProfile = securityProfile;
            tmpUsuario1 = dropItem;
            dataAccessSmart.Remove(dropItem);
            ResourceLock.WaitOne(1000);
            return "Baja de usuario realizada.";
        }

        public IAsyncResult BeginDeleteT_C_Usuario(Profile securityProfile, T_C_Usuario dropItem, AsyncCallback callback, object state)
        {
            T_C_UsuarioAsyncResult asyncResult = new T_C_UsuarioAsyncResult(securityProfile, callback, state);
            ThreadPool.QueueUserWorkItem(new WaitCallback((DeleteT_C_UsuarioCallback)), asyncResult);
            return asyncResult;
        }

        private void DeleteT_C_UsuarioCallback(object asyncResult)
        {
            T_C_AreaAsyncResult t_c_AreaAsyncResult = (T_C_AreaAsyncResult)asyncResult;
            try
            {
                t_c_AreaAsyncResult.CollectionResult = null;
                t_c_AreaAsyncResult.ExceptionTrace = null;
                t_c_AreaAsyncResult.MessageResult = DeleteT_C_Usuario(SecurityProgram.PcProfile, tmpUsuario1);

            }
            catch (Exception ex)
            {
                t_c_AreaAsyncResult.CollectionResult = null;
                t_c_AreaAsyncResult.ExceptionTrace = ex;
                t_c_AreaAsyncResult.MessageResult = string.Empty;
            }
            finally
            {
                t_c_AreaAsyncResult.OnCompleted();
                tmpUsuario1 = null;
            }
        }

        public string EndDeleteT_C_Usuario(IAsyncResult asyncResult)
        {
            string msg = string.Empty;
            using (T_C_UsuarioAsyncResult t_c_AreaAsyncResult = asyncResult as T_C_UsuarioAsyncResult)
            {
                asyncResult.AsyncWaitHandle.WaitOne();
                msg = t_c_AreaAsyncResult.MessageResult;
            }
            return msg;
        }
        
        #endregion 

		#endregion
	}
}
